/*
 * LOGO dialect, KTurtle version.
 */

%{
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "token.h"
#include "scan.h"

int g_line_no;


%}

digit          [0-9]
letter         [a-zA-Z]
id_char        {letter}|{digit}
integer        {digit}+
number         {integer}|({integer}\.{digit}+)
newline        [\n\r]
identifier     {letter}{id_char}*
string         \"[^"\n]*\"
comment        #[^\n]*
space          [ \t]+

%%
"+"            {return TOKEN_PLUS;}
"-"            {return TOKEN_MINUS;}
"*"            {return TOKEN_MUL;}
"/"            {return TOKEN_DIV;}
","            {return TOKEN_COMMA;}
"["            {return TOKEN_LEFT_SQUARE;}
"]"            {return TOKEN_RIGHT_SQUARE;}
"{"            {return TOKEN_COMPOUND_START;}
"}"            {return TOKEN_COMPOUND_END;}
"("            {return TOKEN_LEFT_BRACKET;} 
")"            {return TOKEN_RIGHT_BRACKET;}
"="            {return TOKEN_ASSIGN;}
"<"            {return TOKEN_LT;}
">"            {return TOKEN_GT;}
"<="           {return TOKEN_LE;}
">="           {return TOKEN_GE;}
"=="           {return TOKEN_EQUAL;}
"!="           {return TOKEN_NOT_EQUAL;}
"return"       {return TOKEN_RETURN;}
"reset"        {return TOKEN_RESET;}
"canvassize"   {return TOKEN_CANVASSIZE;}
"cs"           {return TOKEN_CANVASSIZE;}
"canvascolor"  {return TOKEN_CANVASCOLOR;}
"cc"           {return TOKEN_CANVASCOLOR;}
"pencolor"     {return TOKEN_PENCOLOR;}
"pc"           {return TOKEN_PENCOLOR;}
"penwidth"     {return TOKEN_PENWIDTH;}
"pw"           {return TOKEN_PENWIDTH;}
"go"           {return TOKEN_GO;}
"turnright"    {return TOKEN_TURNRIGHT;}
"tr"           {return TOKEN_TURNRIGHT;}
"turnleft"     {return TOKEN_TURNLEFT;}
"tl"           {return TOKEN_TURNLEFT;}
"forward"      {return TOKEN_FORWARD;}
"fw"           {return TOKEN_FORWARD;}
"backward"     {return TOKEN_BACKWARD;}
"bw"           {return TOKEN_BACKWARD;}
"direction"    {return TOKEN_DIRECTION;}
"dir"          {return TOKEN_DIRECTION;}
"repeat"       {return TOKEN_REPEAT;}
"fontsize"     {return TOKEN_FONTSIZE;}
"print"        {return TOKEN_PRINT;}
"hide"         {return TOKEN_HIDE;}
"sh"           {return TOKEN_HIDE;}
"learn"        {return TOKEN_LEARN;}
"wait"         {return TOKEN_WAIT;}
"clear"        {return TOKEN_CLEAR;}
"cr"           {return TOKEN_CLEAR;}
"for"          {return TOKEN_FOR;}
"to"           {return TOKEN_TO;}
"if"           {return TOKEN_IF;}
"else"         {return TOKEN_ELSE;}
"while"        {return TOKEN_WHILE;}
"penup"        {return TOKEN_PENUP;}
"pu"           {return TOKEN_PENUP;}
"pendown"      {return TOKEN_PENDOWN;}
"pd"           {return TOKEN_PENDOWN;}
"center"       {return TOKEN_CENTER;}
"gox"          {return TOKEN_GOX;}
"goy"          {return TOKEN_GOY;}
"wrapon"       {return TOKEN_WRAPON;}
"wrapoff"      {return TOKEN_WRAPOFF;}
"show"         {return TOKEN_SHOW;}
"ss"           {return TOKEN_SHOW;}
"message"      {return TOKEN_MESSAGE;}
"break"			{return TOKEN_BREAK;}
"continue"		{return TOKEN_CONTINUE;}
{number}       {return TOKEN_NUMBER;}
{identifier}   {return TOKEN_ID;}
{comment}      {;}
{space}        {;}
{newline}      {g_line_no++;}
{string}       {return TOKEN_STRING;}
.              {return TOKEN_ERROR;}
%%


void start_scanning (FILE* file)
{
   assert (file);
   g_line_no = 1;
   yyin = file;
}

int get_line_no ()
{
   return g_line_no;
}

const char* get_token_string ()
{
   return (const char*) yytext;
}

token_t  get_token()
{
   token_t cur_token;
   cur_token = yylex();
#ifdef __LISTING__
   printf ("%d\t", g_line_no);
   print_token (NULL, cur_token, yytext);
#endif /* __LISTING__ */
   return cur_token;
}

void print_token (FILE* file, token_t token, const char* str )
{
   if (!file) {
      file = stdout;
   }

   switch (token) {
   case TOKEN_RESET:
   case TOKEN_RETURN:
   case TOKEN_WAIT:
   case TOKEN_CLEAR:
   case TOKEN_HIDE:
   case TOKEN_LEARN:
   case TOKEN_FOR:
   case TOKEN_TO:
   case TOKEN_REPEAT:
   case TOKEN_WHILE:
   case TOKEN_CANVASSIZE:
   case TOKEN_CANVASCOLOR:
   case TOKEN_PENCOLOR:
   case TOKEN_PENWIDTH:
   case TOKEN_GO:
   case TOKEN_DIRECTION:
   case TOKEN_TURNRIGHT:
   case TOKEN_TURNLEFT:
   case TOKEN_FORWARD:
   case TOKEN_BACKWARD:
   case TOKEN_FONTSIZE:
   case TOKEN_PRINT:
   case TOKEN_IF:
   case TOKEN_ELSE:
   case TOKEN_CENTER:
   case TOKEN_GOX:
   case TOKEN_GOY:
   case TOKEN_PENUP:
   case TOKEN_PENDOWN:
   case TOKEN_WRAPOFF:
   case TOKEN_WRAPON:
   case TOKEN_SHOW:
   case TOKEN_MESSAGE:
   case TOKEN_BREAK:
   case TOKEN_CONTINUE:
      fprintf (file, "reserved word: %s\n", str);
      break;

   case TOKEN_EQUAL:
      fprintf (file, "Equal decision %s\n", str);
      break;
   case TOKEN_NOT_EQUAL:
      fprintf (file, "Not equal decision %s\n", str);
      break;

   case TOKEN_PLUS:
   case TOKEN_MINUS:
   case TOKEN_MUL:
   case TOKEN_DIV:
   case TOKEN_LT:
   case TOKEN_GT:
   case TOKEN_ASSIGN:
   case TOKEN_COMMA:
   case TOKEN_LEFT_BRACKET:
   case TOKEN_RIGHT_BRACKET:
   case TOKEN_LEFT_SQUARE:
   case TOKEN_RIGHT_SQUARE:
      fprintf (file, "%s\n", str);
      break;

   case TOKEN_NUMBER:
      fprintf (file, "NUM, val= %s\n",str);
      break;
   case TOKEN_ID:
      fprintf (file, "ID, name= %s\n",str);
      break;
   case TOKEN_ERROR:
      fprintf (file, "ERROR, %s\n", str);
      break;
   case TOKEN_STRING:
      fprintf (file, "String, %s\n", str);
      break;

   case TOKEN_EOF:
      fprintf (file, "END!\n");
      break;

   default: /* should never happen */
      fprintf (file, "STRANGE token, %d, %s\n", token, str);
      assert (0);
   }
}


